Periodischer Job mit unabhängigen Steps
Jobverarbeitung is in vielen Bereichen und für viele Funktionalitäten wichtig. Jobeinplanungen sind eine gängige Technik, die jahrzehntelang erprobt ist. Kürzlich bin ich in einem Projekt auf eine Anforderung gestoßen, die nicht so ohne Weiteres mit den Standardmitteln der Jobeinplanung möglich war.
Anforderung
Es soll ein periodischer Job mit mehreren Steps eingeplant werden, deren Verarbeitungsschritte (Steps) unabhängig voneinander sind. Unabhängig heißt in diesem Fall, dass ein Verarbeitungsschritt, der durch einen Kurzdump abbricht, die Ausführung der anderen Schritte nicht beeinträchtigen soll.
Möglichkeit 1
Die erste auf der Hand liegende Möglichkeit ist, einen Job periodisch einzuplanen, der einzelne Verarbeitungsschritte enthält. Leider bricht der gesamte Job ab, wenn einer der Verarbeitungsschritte durch einen Shortdump abbricht. Diese Möglichkeit kommt also nicht in Betracht.
Möglichkeit 2
Die zweite Möglichkeit wäre, die einzelnen Verarbeitungsschritte als einzelne Jobs zu definieren und jeweils den einen Job als Vorgänger des jeweils nächsten Jobs zu definieren. Aber auch hier gibt es eine Einschränkung: Diese Jobs können nicht periodisch geplant werden.
Lösung
Die Lösung für mich war in diesem Fall natürlich ein ABAP Programm. Das folgende Programm kann man periodisch als Job einplanen und hier bis zu fünf Programme unabhängig voneinander, jeweils mit Vorgänger – Nachfolger-Beziehung, definieren. Wenn das Programm ausgeführt wird, startet es das erste Programm sofort als Job. Das zweite Programm wird gestartet, wenn der Job für das erste Programm beendet wurde und so weiter. Dabei ist es unerheblich, ob der Vorgängerjob regulär beendet wurde oder abgebrochen ist.
Das Programm ist fest auf fünf Verarbeitungsschritte ausgelegt. Es kann einfach auf weitere Steps erweitert werden. Sofern noch sehr viele Verarbeitungsschritte verwaltet werden sollten, sollte man die Verarbeitung dynamisch programmieren. Dafür müsste man jedoch auch die Eingabe für die Definition der Verarbeitungsschritte so anpassen, dass die einzelnen Programme in einer Liste (Grid) eingegeben werden können.

Coding
REPORT z_schedule_05_jobs_periodic.
PARAMETERS nam1 TYPE btcjob OBLIGATORY.
PARAMETERS rep1 TYPE syrepid OBLIGATORY.
PARAMETERS var1 TYPE raldb_vari OBLIGATORY.
SELECTION-SCREEN SKIP 1.
PARAMETERS nam2 TYPE btcjob.
PARAMETERS rep2 TYPE syrepid.
PARAMETERS var2 TYPE raldb_vari.
SELECTION-SCREEN SKIP 1.
PARAMETERS nam3 TYPE btcjob.
PARAMETERS rep3 TYPE syrepid.
PARAMETERS var3 TYPE raldb_vari.
SELECTION-SCREEN SKIP 1.
PARAMETERS nam4 TYPE btcjob.
PARAMETERS rep4 TYPE syrepid.
PARAMETERS var4 TYPE raldb_vari.
SELECTION-SCREEN SKIP 1.
PARAMETERS nam5 TYPE btcjob.
PARAMETERS rep5 TYPE syrepid.
PARAMETERS var5 TYPE raldb_vari.
CLASS lcx_job DEFINITION INHERITING FROM cx_static_check.
ENDCLASS.
CLASS lcl_define_job DEFINITION.
PUBLIC SECTION.
METHODS constructor
IMPORTING
iv_name TYPE btcjob
iv_report TYPE syrepid
iv_variant TYPE raldb_vari
RAISING
lcx_job.
METHODS start
IMPORTING
iv_pred_jobcount TYPE btcjobcnt OPTIONAL
iv_pred_jobname TYPE btcjob OPTIONAL
RAISING
lcx_job.
DATA mv_jobcount TYPE btcjobcnt.
DATA mv_jobname TYPE btcjob.
DATA mv_released TYPE abap_bool.
ENDCLASS.
CLASS lcl_define_job IMPLEMENTATION.
METHOD constructor.
mv_jobname = iv_name.
CALL FUNCTION 'JOB_OPEN'
EXPORTING
jobname = iv_name
IMPORTING
jobcount = mv_jobcount
EXCEPTIONS
cant_create_job = 1
invalid_job_data = 2
jobname_missing = 3
OTHERS = 4.
IF sy-subrc = 0.
CALL FUNCTION 'JOB_SUBMIT'
EXPORTING
authcknam = sy-uname
jobcount = mv_jobcount
jobname = iv_name
report = iv_report
variant = iv_variant
EXCEPTIONS
bad_priparams = 1
bad_xpgflags = 2
invalid_jobdata = 3
jobname_missing = 4
job_notex = 5
job_submit_failed = 6
lock_failed = 7
program_missing = 8
prog_abap_and_extpg_set = 9
OTHERS = 10.
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE lcx_job.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD start.
CALL FUNCTION 'JOB_CLOSE'
EXPORTING
jobcount = mv_jobcount
jobname = mv_jobname
pred_jobcount = iv_pred_jobcount
pred_jobname = iv_pred_jobname
strtimmed = SWITCH #( iv_pred_jobcount WHEN space THEN 'X' ELSE space )
IMPORTING
job_was_released = mv_released
EXCEPTIONS
cant_start_immediate = 1
invalid_startdate = 2
jobname_missing = 3
job_close_failed = 4
job_nosteps = 5
job_notex = 6
lock_failed = 7
invalid_target = 8
OTHERS = 9.
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE lcx_job.
ENDIF.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
TRY.
DATA(job1) = NEW lcl_define_job(
iv_name = nam1
iv_report = rep1
iv_variant = var1 ).
job1->start( ).
IF rep2 IS NOT INITIAL.
DATA(job2) = NEW lcl_define_job(
iv_name = nam2
iv_report = rep2
iv_variant = var2 ).
job2->start(
iv_pred_jobname = job1->mv_jobname
iv_pred_jobcount = job1->mv_jobcount ).
ENDIF.
IF rep3 IS NOT INITIAL.
DATA(job3) = NEW lcl_define_job(
iv_name = nam3
iv_report = rep3
iv_variant = var3 ).
job3->start(
iv_pred_jobname = job2->mv_jobname
iv_pred_jobcount = job2->mv_jobcount ).
ENDIF.
IF rep4 IS NOT INITIAL.
DATA(job4) = NEW lcl_define_job(
iv_name = nam4
iv_report = rep4
iv_variant = var4 ).
job4->start(
iv_pred_jobname = job3->mv_jobname
iv_pred_jobcount = job3->mv_jobcount ).
ENDIF.
IF rep5 IS NOT INITIAL.
DATA(job5) = NEW lcl_define_job(
iv_name = nam5
iv_report = rep5
iv_variant = var5 ).
job5->start(
iv_pred_jobname = job4->mv_jobname
iv_pred_jobcount = job4->mv_jobcount ).
ENDIF.
CATCH lcx_job.
MESSAGE 'Error job creation!' TYPE 'I'.
ENDTRY.
- Automatisches Eingabefeld [SAPGUI] - 9. Oktober 2025
- So verhinderst du Jobstarts zur falschen Zeit - 15. September 2025
- [apple] iCloud-Photos herunterladen - 21. Juli 2025


